<template>
  <div class="home">
          <h1>{{v2count}}</h1>
          <h1>计算属性：{{v2com}}</h1>
          <button @click="toplus">加1</button>
          <hr>
          <h1>{{v3count}}</h1>
          <h1>计算属性：{{v3COM}}---{{v3C5}}</h1>
          
          <button @click="toChange">改变</button>
          <hr>
          <h1>渲染reactive数据  :{{state.myname}}</h1>
          <h1>对象：{{state.obj.name}}</h1>
          <button @click="changeName">改变数据</button>
          <hr>
          <h1>{{color}}</h1>
          <h1>{{city}}</h1>
          <button @click="changeCity">改变城市</button>

  </div>
</template>

<script>
    
    // vue3 是 组合式api写法（compostionApi） vue2 是配置项api的写法
    // vue3 更好的支持ts 
    // vue3 双向绑定原理变为proxy 代理，解决 vue2数组和对象 新增属性无法及时响应的问题
    // vue3 优化了虚拟dom diff算法
    // vue3 打包树摇优化 tree-shaking 基于es6 的commonjs规范，按需打包

    // vue3 支持几乎所有的vue2语法
    // vue3 的非语法糖写法 是将setup函数 写在配置项api里面
    import {ref,computed,reactive,toRefs,watch} from 'vue'

    export default {
      name:"home",
      data(){
        return {
          v2count:1,
        }
      },
      methods:{
        toplus(){
          this.v2count++
        }
      },
      computed:{
        v2com(){
          return this.v2count*2
        }
      },
      // vue3 的setup 函数 组件加载的时候执行的钩子
      // setup函数里面没有 this指向 
      // setup函数 代替了vue2的 beforeCreate created beforeMount
      setup(){
        // vue3 所有的代码 都写在setup里面
        // vue3 创建响应式数据的方式 ref 
        //1.  ref 创建的响应式数据，需要通过.value来访问和修改
        // 2. ref 页面使用 不需要.value 
        // 3. ref 响应式原理是 Object.defineProperty
        // 4.ref 一般用来创建基本数据类型
        let v3count=ref(1)//
        // 非语法糖写法 需要在setup函数的返回值中返回组件需要的数据，函数，计算属性等
        // 改变数据的函数 vue3的函数 都写成箭头函数，避免this指向问题
        let toChange=()=>{
          v3count.value++
        }
        // vue3的计算属性computed  
        // 对ref，reactive ，props, vuex 等数据做处理
        let v3COM=computed(()=>{
          return v3count.value*2
        })
        // 成5 的计算属性
        let v3C5=computed(()=>v3count.value*5)

        // 4. reactive 创建响应式数据的 方法 参数是一个对象
        // reactive 响应式原理式 proxy代理完成
        // 访问reactive内容 需要 类似对象变量名.属性 
        // reactive 一次性可以创建多个数据
        let state=reactive({
           myname:"张三",
           list:["汽车","飞机","火车","轮船"],
           obj:{
             name:"李四",
             age:18
           }
        })

        let mydata=reactive({
            color:"红色",
            city:"廊坊"
        })
        // 改变reactive数据的值
        let changeName=()=>{
          state.myname="王德发"
        }
        // 改变城市的方法
        let changeCity=()=>{
          mydata.city="北京"
        }

        // 6. vue3 watch 监听数据变化
        // 监听ref的变化   watch("监听的数据",回调函数,{配置项})
        watch(v3count,(newVal,oldVal)=>{
          console.log(newVal,oldVal,'新的值和旧的值')
        })
        // 监听reactive数据的变化 watch(()=>state.myname,回调函数,{配置项})
        watch(()=>state.m,(newVal,oldVal)=>{
             console.log(newVal,oldVal,'reactive新的值和旧的值')
        },{
          immediate:true, // 立即执行
          deep:true//深度监听
        })

        

        return {
          v3count,
          toChange,
          v3COM,
          v3C5,
          state,
          changeName,
          changeCity,
             // mydata 扩展导出 页面使用 只要具体的属性名即可
            // 5. toRefs 可以通过toRefs 将reactive对象中的属性转成ref对象
          ...toRefs(mydata)

       
        }
      }
    }
</script>
